﻿/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#ifndef MK_UTIL_H
#define MK_UTIL_H
#include "MkUtil/MkTypes.h"
#include "MkTime.h"

class MkApi CMkUtil
{
public:
    static Uint32 GetVersion(MkString& Version);
    static Uint32 GetRandomNumber();
    static MkString &CreateRandomString(int nLen, MkString &Str);
    static BOOL CheckValidHttpUrl(const MkString &HttpUrl);
    static BOOL CheckVaildRtspUrl(const MkString &RtspUrl);
    static BOOL CheckVaildRtmpUrl(const MkString &RtmpUrl);
    static BOOL CheckValidIp(const MkString& Ip);
    static Uint32 GetMkHttpUrl(const MkString &HttpUrl, MkString &MkHttpUrl);
    static Uint32 GetSystemCpuThreadNum(Uint32 &CpuThreadNum);
    static SOCKET CreateListenSocket(Uint16 Port, BOOL IsTcp = TRUE, const MkString& Host = "");
    static SOCKET CreateClientSocket(const MkString &Host, Uint16 Port, int WaitTime);  //minsec
    static Uint32 CheckHttpUrlConnectAbled(const MkString &HttpUrl);
    static Uint32 CheckHostPortConnectAbled(const MkString &Host, Uint16 Port);
    static Uint32 CheckUdpIsUseAbled(Uint16 Port, const MkString& Host = "");
    static Uint32 CheckTcpIsUseAbled(Uint16 Port, const MkString& Host = "");
    static Uint32 GetFreeTcpPort(Uint16 BeginPort, Uint16 EndPort, Uint16 CurPort, Uint16& FreePort);
    static Uint32 GetFreeUdpPort(Uint16 BeginPort, Uint16 EndPort, Uint16 CurPort, Uint16& FreePort);
    static Uint32 GetLocalThreadId();
    static Uint32 ByteToString(const Uint8 *pcStr, Uint32 nLen, MkString &str, BOOL bLowLetters = FALSE);
    static Uint8 ByteToChar(Uint8 ucByte);
    static Uint32 StringToByte(const MkString &str, Uint8 *pcStr, Uint32 &nLen);
    static MkString &Replace(MkString &str, const MkString &before, const MkString &after);
    static Uint32 StringSplit(const MkString &Src, const MkString &SplitStr, MkVectorString &VesDst);
    static Uint32 BufferSplit(const Uint8* pSrc, Uint32 SrcLen, const Uint8* SplitBuf, Uint32 SplitLen, MkVector<const Uint8*>& VecDst, MkVector<Uint32>& VecLen);
    static void TrimString(MkString& Str);
    static Uint32 SplitPort(const MkString &strPort, MkString &Host, Uint16 &Port);
    static MkString MyRegexReplace(const MkString &strFrom, const MkString &strRegex, const MkString &Fmt);
    static MkString SafeMkString(const char *pbuf);
    static double SafeAtof(const char *pbuf);
    static Uint32 SafeAtoi(const char *pbuf);
    static Uint32 SafeAtoi(const MkString& StrBuf);
    static Uint32 RtspUrlParse(const MkString &RtspUrl, MkString &Host, Uint16 &Port);
    static Uint32 RtmpUrlParse(const MkString &RtspUrl, MkString &Host, Uint16 &Port);
    static Uint32 HttpUrlParse(const MkString &HttpUrl, MkString &Host, Uint16 &Port, MkString& Path);
    static Uint32 GetLocalIp(MkString& LocalIp);
    static BOOL IsLanIp(const MkString& Ip);  //lan ip not nat ip
    static Uint32 StringToAscii(const MkString& strInput, MkString& strOutput);
    static BOOL IsHex(Uint8 Value);
    //read Content +nPost Line
    //OUT StrLine and LineEndPos  line end is \n or \r\n
    static Uint32 BufferReadLine(const MkString& Content, INOUT Uint32 &nPos, OUT MkString& StrLine);
    static Uint32 ReadLine(const Int8* Content, Uint32 nLen, INOUT Uint32 &nPos, OUT MkString& strLine);
    static Uint32 Gbk2Utf8(const MkString &strGbk, MkString &strUtf8);
    static Uint32 Utf8ToGbk(const MkString &strUtf8, MkString &strGbk);
    static Uint32 GetOneIpByHostName(const MkString& HostName, MkString& IpAddr);
    static Uint32 ReadTextProtocolHead(const Int8* Content, Uint32 nLen, Uint32& nUsed);
    static BOOL EndByString(const MkString& Content, const MkString& strEnd);
    static BOOL BeginByString(const MkString& Content, const MkString& strBegin);
    //inline functions
    static void Packet64Bit(Uint8 *pBuf, INOUT Uint32& Offset, Uint64 Value)
    {
        pBuf[Offset] = (Value >> 56) & 0xFF;
        pBuf[Offset + 1] = (Value >> 48) & 0xFF;
        pBuf[Offset + 2] = (Value >> 40) & 0xFF;
        pBuf[Offset + 3] = (Value >> 32) & 0xFF;
        pBuf[Offset + 4] = (Value >> 24) & 0xFF;
        pBuf[Offset + 5] = (Value >> 16) & 0xFF;
        pBuf[Offset + 6] = (Value >> 8) & 0xFF;
        pBuf[Offset + 7] = Value & 0xFF;
        Offset += 8;
    }

    static void Packet32Bit(Uint8 *pBuf, INOUT Uint32& Offset, Uint32 Value)
    {
        pBuf[Offset] = (Value >> 24) & 0xFF;
        pBuf[Offset + 1] = (Value >> 16) & 0xFF;
        pBuf[Offset + 2] = (Value >> 8) & 0xFF;
        pBuf[Offset + 3] = Value & 0xFF;
        Offset += 4;
    }

    static void Packet24Bit(Uint8 *pBuf, INOUT Uint32& Offset, Uint32 Value)
    {
        pBuf[Offset] = (Value >> 16) & 0xFF;
        pBuf[Offset + 1] = (Value >> 8) & 0xFF;
        pBuf[Offset + 2] = Value & 0xFF;
        Offset += 3;
    }

    static void Packet16Bit(Uint8 *pBuf, INOUT Uint32& Offset, Uint16 Value)
    {
        pBuf[Offset] = (Value >> 8) & 0xFF;
        pBuf[Offset + 1] = Value & 0xFF;
        Offset += 2;
    }

    static void Packet8Bit(Uint8 *pBuf, INOUT Uint32& Offset, Uint8 Value)
    {
        pBuf[Offset] = Value & 0xFF;
        Offset += 1;
    }

    static Uint32 Read32Bit(const Uint8* pBuf, INOUT Uint32& Offset)
    {
        Uint32 nRet = (pBuf[Offset] << 24) | (pBuf[Offset + 1] << 16) | (pBuf[Offset + 2] << 8) | pBuf[Offset + 3];
        Offset += 4;
        return nRet;
    }

    static Uint32 Read24Bit(const Uint8* pBuf, INOUT Uint32& Offset)
    {
        Uint32 nRet = (pBuf[Offset] << 16) | (pBuf[Offset + 1] << 8) | pBuf[Offset + 2];
        Offset += 3;
        return nRet;
    }

    static Uint64 Read64Bit(const Uint8* pBuf, INOUT Uint32& Offset)
    {
        Uint64 nRet = (pBuf[Offset] << 24);
        nRet |= (pBuf[Offset + 1] << 16);
        nRet |= (pBuf[Offset + 2] << 8);
        nRet |= pBuf[Offset + 3];
        nRet = nRet << 32;
        nRet |= (pBuf[Offset + 4] << 24);
        nRet |= (pBuf[Offset + 5] << 16);
        nRet |= (pBuf[Offset + 6] << 8);
        nRet |= pBuf[Offset + 7];
        Offset += 8;
        return nRet;
    }

    static Uint16 Read16Bit(const Uint8* pBuf, INOUT Uint32& Offset)
    {
        Uint16 nRet = (pBuf[Offset] << 8) | pBuf[Offset + 1];
        Offset += 2;
        return nRet;
    }

    static Uint8 Read8Bit(const Uint8* pBuf, INOUT Uint32& Offset)
    {
        Uint8 nRet = pBuf[Offset];
        Offset += 1;
        return nRet;
    }
    static const MkString& GetEmptyString() { return m_EmptyString; }
private:
    static MkString m_EmptyString;
};
#endif
